﻿layui.define(['jquery','toast'], function (exports) {
    "use strict";

    var $ = layui.jquery;
    var toast = layui.toast;
    var lscom = lscom || {};

    /* Application paths *****************************************/

    //Current application root path (including virtual directory if exists).
    lscom.appPath = lscom.appPath || '/';
    lscom.pageLoadTime = new Date();

    //Converts given path to absolute path using lscom.appPath variable.
    lscom.toAbsAppPath = function (path) {
        if (path.indexOf('/') == 0) {
            path = path.substring(1);
        }

        return ls.appPath + path;
    };

    /* UTILS ***************************************************/

    lscom.utils = lscom.utils || {};

    /* Creates a name namespace.
    *  Example:
    *  var taskService = lscom.utils.createNamespace(lscom, 'services.task');
    *  taskService will be equal to lscom.services.task
    *  first argument (root) must be defined first
    ************************************************************/
    lscom.utils.createNamespace = function (root, ns) {
        var parts = ns.split('.');
        for (var i = 0; i < parts.length; i++) {
            if (typeof root[parts[i]] == 'undefined') {
                root[parts[i]] = {};
            }

            root = root[parts[i]];
        }

        return root;
    };

    /* Find and replaces a string (search) to another string (replacement) in
    *  given string (str).
    *  Example:
    *  lscom.utils.replaceAll('This is a test string', 'is', 'X') = 'ThX X a test string'
    ************************************************************/
    lscom.utils.replaceAll = function (str, search, replacement) {
        var fix = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
        return str.replace(new RegExp(fix, 'g'), replacement);
    };
    lscom.utils.strTrim = function (str) {
        return (str || "").replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g, "");
    }
    lscom.utils.getstrlength = function (str) {
        str = lscom.utils.strTrim(str);  //去除字符串的左右两边空格
        var strlength = str.length;
        if (!strlength) {  //如果字符串长度为零，返回零
            return 0;
        }
        var chinese = str.match(/[\u4e00-\u9fa5]/g); //匹配中文，match返回包含中文的数组
        return strlength + (chinese ? chinese.length : 0); //计算字符个数
    }
    /* Formats a string just like string.format in C#.
    *  Example:
    *  lscom.utils.formatString('Hello {0}','Tuana') = 'Hello Tuana'
    ************************************************************/
    lscom.utils.formatString = function () {
        if (arguments.length < 1) {
            return null;
        }

        var str = arguments[0];

        for (var i = 1; i < arguments.length; i++) {
            var placeHolder = '{' + (i - 1) + '}';
            str = lscom.utils.replaceAll(str, placeHolder, arguments[i]);
        }

        return str;
    };

    lscom.utils.toPascalCase = function (str) {
        if (!str || !str.length) {
            return str;
        }

        if (str.length === 1) {
            return str.charAt(0).toUpperCase();
        }

        return str.charAt(0).toUpperCase() + str.substr(1);
    }

    lscom.utils.toCamelCase = function (str) {
        if (!str || !str.length) {
            return str;
        }

        if (str.length === 1) {
            return str.charAt(0).toLowerCase();
        }

        return str.charAt(0).toLowerCase() + str.substr(1);
    }

    lscom.utils.truncateString = function (str, maxLength) {
        if (!str || !str.length || str.length <= maxLength) {
            return str;
        }

        return str.substr(0, maxLength);
    };

    lscom.utils.truncateStringWithPostfix = function (str, maxLength, postfix) {
        postfix = postfix || '...';

        if (!str || !str.length || str.length <= maxLength) {
            return str;
        }

        if (maxLength <= postfix.length) {
            return postfix.substr(0, maxLength);
        }

        return str.substr(0, maxLength - postfix.length) + postfix;
    };

    lscom.utils.isFunction = function (obj) {
        if ($) {
            //Prefer to use jQuery if possible
            return $.isFunction(obj);
        }

        //alternative for $.isFunction
        return !!(obj && obj.constructor && obj.call && obj.apply);
    };

    lscom.utils.formatDate = function () {
        
    }

    /**
     * parameterInfos should be an array of { name, value } objects
     * where name is query string parameter name and value is it's value.
     * includeQuestionMark is true by default.
     */
    lscom.utils.buildQueryString = function (parameterInfos, includeQuestionMark) {
        if (includeQuestionMark === undefined) {
            includeQuestionMark = true;
        }

        var qs = '';

        function addSeperator() {
            if (!qs.length) {
                if (includeQuestionMark) {
                    qs = qs + '?';
                }
            } else {
                qs = qs + '&';
            }
        }

        for (var i = 0; i < parameterInfos.length; ++i) {
            var parameterInfo = parameterInfos[i];
            if (parameterInfo.value === undefined) {
                continue;
            }

            if (parameterInfo.value === null) {
                parameterInfo.value = '';
            }

            addSeperator();

            if (parameterInfo.value.toJSON && typeof parameterInfo.value.toJSON === "function") {
                qs = qs + parameterInfo.name + '=' + encodeURIComponent(parameterInfo.value.toJSON());
            } else if (Array.isArray(parameterInfo.value) && parameterInfo.value.length) {
                for (var j = 0; j < parameterInfo.value.length; j++) {
                    if (j > 0) {
                        addSeperator();
                    }

                    qs = qs + parameterInfo.name + '[' + j + ']=' + encodeURIComponent(parameterInfo.value[j]);
                }
            } else {
                qs = qs + parameterInfo.name + '=' + encodeURIComponent(parameterInfo.value);
            }
        }

        return qs;
    }

    /**
     * Sets a cookie value for given key.
     * This is a simple implementation created to be used by ABP.
     * Please use a complete cookie library if you need.
     * @param {string} key
     * @param {string} value 
     * @param {Date} expireDate (optional). If not specified the cookie will expire at the end of session.
     * @param {string} path (optional)
     */
    lscom.utils.setCookieValue = function (key, value, expireDate, path, domain) {
        var cookieValue = encodeURIComponent(key) + '=';

        if (value) {
            cookieValue = cookieValue + encodeURIComponent(value);
        }

        if (expireDate) {
            cookieValue = cookieValue + "; expires=" + expireDate.toUTCString();
        }

        if (path) {
            cookieValue = cookieValue + "; path=" + path;
        }

        if (domain) {
            cookieValue = cookieValue + "; domain=" + domain;
        }

        document.cookie = cookieValue;
    };

    /**
     * Gets a cookie with given key.
     * This is a simple implementation created to be used by ABP.
     * Please use a complete cookie library if you need.
     * @param {string} key
     * @returns {string} Cookie value or null
     */
    lscom.utils.getCookieValue = function (key) {
        var equalities = document.cookie.split('; ');
        for (var i = 0; i < equalities.length; i++) {
            if (!equalities[i]) {
                continue;
            }

            var splitted = equalities[i].split('=');
            if (splitted.length != 2) {
                continue;
            }

            if (decodeURIComponent(splitted[0]) === key) {
                return decodeURIComponent(splitted[1] || '');
            }
        }

        return null;
    };

    /**
     * Deletes cookie for given key.
     * This is a simple implementation created to be used by lscom.
     * Please use a complete cookie library if you need.
     * @param {string} key
     * @param {string} path (optional)
     */
    lscom.utils.deleteCookie = function (key, path) {
        var cookieValue = encodeURIComponent(key) + '=';

        cookieValue = cookieValue + "; expires=" + (new Date(new Date().getTime() - 86400000)).toUTCString();

        if (path) {
            cookieValue = cookieValue + "; path=" + path;
        }

        document.cookie = cookieValue;
    }

    /**
     * Gets the domain of given url
     * @param {string} url 
     * @returns {string} 
     */
    lscom.utils.getDomain = function (url) {
        var domainRegex = /(https?:){0,1}\/\/((?:[\w\d-]+\.)+[\w\d]{2,})/i;
        var matches = domainRegex.exec(url);
        return (matches && matches[2]) ? matches[2] : '';
    }

    /* TIMING *****************************************/
    lscom.timing = lscom.timing || {};

    lscom.timing.utcClockProvider = (function () {

        var toUtc = function (date) {
            return Date.UTC(
                date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(),
                date.getUTCSeconds(), date.getUTCMilliseconds()
            );
        }

        var now = function () {
            return toUtc(new Date());
        };

        var normalize = function (date) {
            if (!date) {
                return date;
            }

            return new Date(toUtc(date));
        };

        // Public interface ///////////////////////////////////////////////////

        return {
            now: now,
            normalize: normalize,
            supportsMultipleTimezone: true
        };
    })();

    lscom.timing.localClockProvider = (function () {

        var toLocal = function (date) {
            return new Date(
                date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(),
                date.getMilliseconds()
            );
        }

        var now = function () {
            return toLocal(new Date());
        }

        var normalize = function (date) {
            if (!date) {
                return date;
            }

            return toLocal(date);
        }

        // Public interface ///////////////////////////////////////////////////

        return {
            now: now,
            normalize: normalize,
            supportsMultipleTimezone: false
        };
    })();

    lscom.timing.unspecifiedClockProvider = (function () {

        var now = function () {
            return new Date();
        }

        var normalize = function (date) {
            return date;
        }

        // Public interface ///////////////////////////////////////////////////

        return {
            now: now,
            normalize: normalize,
            supportsMultipleTimezone: false
        };
    })();

    lscom.timing.convertToUserTimezone = function (date) {
        var localTime = date.getTime();
        var utcTime = localTime + (date.getTimezoneOffset() * 60000);
        var targetTime = parseInt(utcTime) + parseInt(lscom.timing.timeZoneInfo.windows.currentUtcOffsetInMilliseconds);
        return new Date(targetTime);
    };

    /* CLOCK *****************************************/
    lscom.clock = lscom.clock || {};

    lscom.clock.now = function () {
        if (lscom.clock.provider) {
            return lscom.clock.provider.now();
        }

        return new Date();
    }

    lscom.clock.normalize = function (date) {
        if (lscom.clock.provider) {
            return lscom.clock.provider.normalize(date);
        }

        return date;
    }

    lscom.clock.provider = lscom.timing.unspecifiedClockProvider;

    /* SECURITY ***************************************/
    lscom.security = lscom.security || {};
    lscom.security.antiForgery = lscom.security.antiForgery || {};

    lscom.security.antiForgery.tokenCookieName = 'XSRF-TOKEN';
    lscom.security.antiForgery.tokenHeaderName = 'Authorization';

    lscom.security.antiForgery.getToken = function () {
        return lscom.utils.getCookieValue(lscom.security.antiForgery.tokenCookieName);
    };

    lscom.security.antiForgery.shouldSendToken = function (settings) {
        if (settings.crossDomain === undefined || settings.crossDomain === null) {
            return lscom.utils.getDomain(location.href) === lscom.utils.getDomain(settings.url);
        }

        return !settings.crossDomain;
    };

    /*toast***************************************/
    lscom.notify = lscom.notify || {};
    lscom.notify.success = function (message) {
        toast.success({ title: '提示', message: message, position: 'topRight' });
    };

    lscom.notify.info = function (message) {
        toast.info({ title: '提示', message: message, position: 'topRight' });
    };

    lscom.notify.warn = function (message) {
        toast.warning({ title: '提示', message: message, position: 'topRight' });
    };

    lscom.notify.error = function (message) {
        toast.error({ title: '提示', message: message, position: 'topRight' });
    };
    exports('lscore', lscom);
});